#include "hardAI.h"
#include "mainwindow.h"

HardAI::HardAI(MainWindow* _mainWindow):EasyAI(_mainWindow)
{
    maxDep = 4;
    qDebug() << "AlphaBeta maxDep:" << maxDep;
}

void HardAI::computerMove()
{
    Step *bestStep = NULL;
    int maxMinValues = INT_MIN; //人下完电脑的最低分中最高的

    clock_t startTime = clock();
    QVector<Step *> steps;
    getAllCanSteps(steps);
    //模拟走棋算出最高分
    while (steps.count()) {
        Step *step = steps.back();
        movePiece(step->fromId, step->rowTo, step->colTo);
        if (step->toId >= 0)
            pieces[step->toId].isAlive = false;

        int tmpScore = getMinScore(1, maxMinValues);

        //还原
        if (step->toId >= 0)
            pieces[step->toId].isAlive = true;
        movePiece(step->fromId, step->rowFrom, step->colFrom);

        if (tmpScore > maxMinValues) {
            maxMinValues = tmpScore;
            if (bestStep)
                delete bestStep;
            bestStep = step;
        } else
            delete step;
        steps.removeLast();
    }
    clock_t endTime = clock();
    qDebug() << "耗时：" << endTime - startTime;

    saveStep(bestStep->fromId, bestStep->rowTo, bestStep->colTo, bestStep->toId);
    if (bestStep->toId >= 0)
        pieces[bestStep->toId].isAlive = false;
    movePiece(bestStep->fromId, bestStep->rowTo, bestStep->colTo);
    delete bestStep;
    if(!checkWin())
    {
        mainWindow->resetTimer(true);
        blackStep++;
        mainWindow->updateStep(false,blackStep);
    }
    update();
}

//站在人方计算，人走完电脑的最低分
int HardAI::getMinScore(int lv, int curMaxMinScore)
{
    if (lv >= maxDep || !pieces[4].isAlive || !pieces[20].isAlive)
        return calcScore();
    int minScore = INT_MAX; //电脑下完电脑的最高分中最小的，最小化电脑的最大利益
    QVector<Step*> steps;
    getAllCanSteps(steps); //人的所有可走步
    while (steps.count()){
        Step *step = steps.back();
        movePiece(step->fromId, step->rowTo, step->colTo);
        if (step->toId >= 0)
            pieces[step->toId].isAlive = false;
        //        int tmpScore = calcScore();
        int tmpScore = getMaxScore(lv+1, minScore);
        //还原
        if (step->toId >= 0)
            pieces[step->toId].isAlive = true;
        movePiece(step->fromId, step->rowFrom, step->colFrom);
        //Alpha剪枝
        if (tmpScore <= curMaxMinScore){
            steps.clear();
            return tmpScore;
        }
        if (tmpScore < minScore)
            minScore = tmpScore;
        steps.removeLast();
    }
    return minScore;
}

//电脑下完电脑的最高分
int HardAI::getMaxScore(int lv, int curMinMaxScore)
{
    if (lv >= maxDep || !pieces[4].isAlive || !pieces[20].isAlive)
        return calcScore();
    int maxScore = INT_MIN; //人下完电脑的最低分中最大的，最大化电脑的最小利益
    QVector<Step*> steps;
    getAllCanSteps(steps); //电脑的所有可走步
    while (steps.count()){
        Step *step = steps.back();
        movePiece(step->fromId, step->rowTo, step->colTo);
        if (step->toId >= 0)
            pieces[step->toId].isAlive = false;
        int tmpScore = getMinScore(lv+1, maxScore);
        //还原
        if (step->toId >= 0)
            pieces[step->toId].isAlive = true;
        movePiece(step->fromId, step->rowFrom, step->colFrom);
        //Beta剪枝
        if (tmpScore >= curMinMaxScore) {
            steps.clear();
            return tmpScore;
        }
        if (tmpScore > maxScore)
            maxScore = tmpScore;
        steps.removeLast();
    }
    return maxScore;
}

